
var common = require("./common") 
var db = require("./db");
var kurento = require('kurento-client');


class TKmsManager{
    constructor(){
        this.config={
            db:{
                dbKey:'vSport',
                dbInfo:{
                    host:"tjiot.hhdata.cn" ,
                    port:53306,
                    uid:"root",
                    pwd:"hhuc1115",
                    db:"vSport" ,
                    sqlPath:"D:/gitee/vsport/vsport/web/sqls"
                }
            },
            kms:{
                //kmsUrl:"wss://ssl.hhdata.cn:40014/kurento" ,
                kmsUrl: "wss://wss.hhdata.cn:8433/kurento",
                appPipeName :"vSportPipe",
                infoKey:"hhucKmsInfo"
            }
        }
        this.kmsClient = null;
        this.db = new db.TDBMySql();
        this.objCodeDict ={};
        this.objIdDict ={};
    }
    getClient(){
        var me = this;
        return new Promise((success , faild)=>{
            try{
                var createClient= function(){
                    try{
                        me.objIdDict={};
                        me.objCodeDict ={};
                        kurento( me.config.kms.kmsUrl , function(erClient , client){
                                try{
                                    me.kmsClient = client;  
                                    if( !client || client==null){
                                        success(me.kmsClient);
                                    }
                                    else{
                                        client.closed = false;
                                        client.getServerManager().then(svr=>{
                                            svr.on("ObjectCreated", function(event){
                                                console.log(event);
                                            })
                                            svr.on("ObjectDestroyed", function(event){
                                                console.log(event);
                                            })
                                            client.on ('disconnected' , function(event){
                                                console.log(event);                                        
                                            })
                                        }).then(()=>{             
                                            return me.loadObjsFromDB(me.kmsClient);
                                        }).then(()=>{             
                                            success(me.kmsClient)
                                        });
                                    }
                                }
                                catch(eer){
                                    console.log('--------------------- kms client disconnected.----------------------')
                                    me.kmsClient = null;    
                                    success(me.kmsClient)
                                }
                        }) 
                    }
                    catch(eer){
                        console.log(eer);
                    }
                }
                if( me.kmsClient && me.kmsClient!=null && !me.kmsClient.closed){
                    me.kmsClient.getServerManager(function(ersvr, svr){
                        if( svr && svr!=null){
                            success(me.kmsClient);
                        }
                        else{
                            client = null;
                            success(me.kmsClient);
                        }
                    }); 
                }
                else{
                    createClient();
                }

            }
            catch(er){
                console.log(er);
            }
        })
    }
    loadObjsFromDB(client){
        var me = this;
        return new Promise((success , faild)=>{
            try{ 
                me.db.apps[me.config.db.dbKey] = me.config.db.dbInfo;
                var sql = "SELECT * FROM  v_currentKmsObj";
                me.db.query( me.config.db.dbKey , sql , {} , function(res){
                    var freeIds =[];
                    var loadItem= function(){
                        if( res.result.length>0){
                            var item = res.result.shift();
                            client.getMediaobjectById( item.kmsId, function(erObj , obj){
                                if( obj && obj!=null && !erObj){
                                    obj.info = item;
                                    me.objCodeDict[obj.info.code] = obj;
                                    me.objIdDict[obj.id] = obj;
                                }
                                else{
                                    freeIds.push(item.objId);
                                }
                                loadItem();
                            })
                        }
                        else{
                            if( freeIds.length>0){
                                sql = "delete from T_KmsObj where objId in ("+ freeIds.join(",")+")";
                                me.db.query( me.config.db.dbKey , sql , {} , function(res){
                                    success();
                                });
                            }
                            else{
                                success();
                            }
                        }
                    }
                    loadItem();
                })
            }
            catch(er){
                console.log(er);
            }
        })
    }
    registObj( obj , code , clientId){
        var me = this;
        return new Promise((success , faild)=>{
            try{ 
                var sql = "insert into T_KmsObj( code , kmsId , clientId , createTm) values(:code , :kmsId , :clientId , unix_timestamp(now()))";
                var ps={
                    code:code ,
                    clientId : clientId ,
                    kmsId: obj.id
                }
                me.db.query( me.config.db.dbKey , sql , ps , function(res){
                    if( res && res.result && res.result.insertId && res.result.insertId >0){
                        ps.objId = res.result.insertId ;
                        obj.info = ps;
                        me.objIdDict[obj.id] = obj;
                        me.objCodeDict[code] = obj;
                    }
                    success(obj);
                } )
            }
            catch(er){
                console.log(er);
            }
        })
    }
    registObjById( kmsId , code , clientId){
        var me = this;
        return new Promise((success , faild)=>{
            try{ 
                me.getClient().then(client=>{
                    client.getMediaobjectById(kmsId , function(erFind , obj){
                        if( obj && obj!=null){
                            me.registObj(obj , code , clientId).then(kmsObj=>{
                                success(kmsObj);
                            })
                        }
                        else{
                            success( null);
                        }
                    });
                })
            }
            catch(er){
                console.log(er);
            }
        })
    }
    getObjByCode( code ){
        var me = this;
        var res = null;
        try{ 
            if( me.objCodeDict[code] ){
                res = me.objCodeDict[code] ;
            }
        }
        catch(er){
            console.log(er);
        }
        return res;
    }
    getObjById( kmsId ){
        var me = this;
        var res = null;
        try{ 
            if( me.objIdDict[kmsId] ){
                res = me.objIdDict[kmsId] ;
            }
        }
        catch(er){
            console.log(er);
        }
        return res;
    }
    loadPipe( code , clientId){
        var me = this;
        return new Promise((success , faild)=>{
            try{ 
                me.getClient().then(client=>{
                    var obj = me.getObjByCode(code);
                    if( obj==null){
                        client.create("MediaPipeline").then(pipe=>{
                            return me.registObj(pipe , code , clientId);
                        }).then(obj=>{
                            success(obj);
                        });
                    }
                    else{
                        success(obj);
                    }
                })
            }
            catch(er){
                console.log(er);
            }
        })
    }
    loadPlayer( pipe , code , clientId, srcUrl){
        var me = this;
        var res = me.getObjByCode(code);
        return new Promise((success , faild)=>{
            try{ 
                if( res == null){
                    pipe.create("PlayerEndpoint" ,{uri: srcUrl}).then(playEnd=>{
                        playEnd.on("EndOfStream", function(){
                            playEnd.play();
                        })
                        return me.registObj(playEnd , code , clientId);
                    }).then(obj=>{
                        obj.play( function(erPlay){
                            success(obj);
                        })
                    });
                }
                else{
                    res.getState().then(state=>{
                        if( state=="STOP"){
                            res.play(function(erPlay){
                                success(res);
                            })
                        }
                        else{                            
                            success(res);   
                        }
                    })
                }
            }
            catch(er){
                console.log(er);
            }
        }) 
    }
    loadWebRtcEnd( pipe , code , clientId){
        var me = this;
        var res = me.getObjByCode(code);
        return new Promise((success , faild)=>{
            try{ 
                if( res == null){
                    me.getClient().then(client=>{
                        pipe.create("WebRtcEndpoint").then(end=>{
                            return me.registObj(end , code , clientId);
                        }).then(obj=>{
                            success(obj);
                        });
                    })
                }
                else{
                    success(res);
                }
            }
            catch(er){
                console.log(er);
            } 
        }) 
    }

    regist2WebSvr(webSvr){
        var me = this;
        if( webSvr && webSvr!=null){
            var respJson = function(result , response){
                try{
                    response.send(JSON.stringify(result));
                }
                catch(eer){
                    console.log(eer);
                }
            }
            webSvr.registRoute ( "common" , "kmsManager" , "registObj" , function( result , request , response ){                
                try{
                    var kmsId = result.ps.kmsId ;  
                    var code = result.ps.code ;  
                    var clientId = result.ps.clientId ;   
                    me.registObjById(kmsId , code , clientId).then(obj=>{
                        result.data = (obj && obj.info)?obj.info:null;
                        respJson(result, response);
                    })
                }
                catch(err){
                    console.log(err);
                    respJson(result, response);
                }
            }); 
            webSvr.registRoute ( "common" , "kmsManager" , "getObjByCode" , function( result , request , response ){                
                try{
                    var code = result.ps.code ;  
                    var obj = me.getObjByCode(code);
                    result.data =  (obj && obj.info)?obj.info:null;
                    respJson(result, response);
                }
                catch(err){
                    console.log(err);
                    respJson(result, response);
                }
            }); 
            webSvr.registRoute ( "common" , "kmsManager" ,  "loadPipe" , function( result , request , response ){                
                try{ 
                    var code = result.ps.code ; 
                    var clientId = result.ps.clientId ;   
                    me.loadPipe(code , clientId).then(obj=>{
                        result.data = (obj && obj.info)?obj.info:null;
                        respJson(result, response);
                    }) 
                }
                catch(err){
                    console.log(err);
                    respJson(result, response);
                }
            }); 
            webSvr.registRoute ( "common" , "kmsManager" ,  "loadPlayer" , function( result , request , response ){                
                try{ 
                    var pipeId = result.ps.pipeId ; 
                    var code = result.ps.code ; 
                    var clientId = result.ps.clientId ; 
                    var srcUrl = result.ps.url ;  
                    var pipe = me.objIdDict[pipeId]? me.objIdDict[pipeId]:null;
                    if( pipe && pipe!=null){
                        me.loadPlayer(pipe , code , clientId, srcUrl ).then(obj=>{
                            result.data = (obj && obj.info)?obj.info:null;
                            respJson(result, response);
                        })
                    }
                    else{
                        result.error = "pipeId is error."
                        result.data = null;
                        respJson(result, response);

                    }
                }
                catch(err){
                    console.log(err);
                    respJson(result, response);
                }
            }); 
            webSvr.registRoute ( "common" , "kmsManager" ,  "loadWebRtcEnd" , function( result , request , response ){                
                try{ 
                    var pipeId = result.ps.pipeId ; 
                    var code = result.ps.code ; 
                    var clientId = result.ps.clientId ;  
                    var pipe = me.objIdDict[pipeId]? me.objIdDict[pipeId]:null;
                    if( pipe && pipe!=null){
                        me.loadWebRtcEnd(pipe , code , clientId ).then(obj=>{
                            result.data = (obj && obj.info)?obj.info:null;
                            respJson(result, response);
                        })
                    }
                    else{
                        result.error = "pipeId is error."
                        result.data = null;
                        respJson(result, response);

                    }
                }
                catch(err){
                    console.log(err);
                    respJson(result, response);
                }
            });  
            webSvr.registRoute ( "common" , "kmsManager" ,  "connectMedia" , function( result , request , response ){                
                try{ 
                    var srcId = result.ps.srcId ; 
                    var tarId = result.ps.tarId ; 
                    me.getClient().then(client=>{
                        client.getMediaobjectById(srcId, function(erSrc, src){
                            client.getMediaobjectById(tarId, function(erTar, tar){
                                result.data = {state:0};
                                if( src!= null && tar!=null){
                                    src.connect(tar, function(erConn){
                                        result.data ={state: 1};
                                    })
                                }
                                respJson(result, response);
                            })

                        })
                    }) 
                }
                catch(err){
                    console.log(err);
                    respJson(result, response);
                }
            });  
            webSvr.registRoute ( "common" , "kmsManager" ,  "connectMediaByCode" , function( result , request , response ){                
                try{ 
                    var srcCode = result.ps.srcCode ; 
                    var tarCode = result.ps.tarCode ; 
                    var src = me.getObjByCode(srcCode);
                    var tar = me.getObjByCode(tarCode);
                    result.data = {state:0};
                    if( src!= null && tar!=null){
                        src.connect(tar, function(erConn){
                            result.data ={state: 1};                            
                            respJson(result, response);
                        })
                    }
                    else{
                        respJson(result, response);
                    }
                }
                catch(err){
                    console.log(err);
                    respJson(result, response);
                }
            });  
        }
    }
}
module.exports = {
    TKmsManager : TKmsManager 
}